#include "AnalysisSql.h"


SqlDomain::AnalysisDomain AnalysisSql::createPatient(QString patientName, QString testId, QString imageName){
    // 判断数据是否存在
    QSqlQuery selectQuery(liteDB);
    QString selectSql = QString("SELECT id FROM patient WHERE patientName='%1' and testId='%2' and imageName='%3'").arg(patientName, testId, imageName);
    selectQuery.prepare(selectSql);
    if(!selectQuery.exec()){
        qCritical() << selectQuery.lastError();
        return {-1, patientName, testId, imageName};
    }
    if(selectQuery.next()){
        return {selectQuery.value(0).toInt(), patientName, testId, imageName};
    }

    // 否则插入
    QSqlQuery insertQuery(liteDB);
    QString insertSql = QString("INSERT INTO patient (patientName, testId, imageName) VALUES ('%1', '%2', '%3')").arg(patientName, testId, imageName);
    insertQuery.prepare(insertSql);

    if(!insertQuery.exec()){
        qCritical() << insertQuery.lastError();
        return {-1, patientName, testId, imageName};
    }
    return {insertQuery.lastInsertId().toInt(), patientName, testId, imageName};
}

bool AnalysisSql::updateTaskStatus(int id, QString taskId, QString taskOptions, int taskStatus, QString errMsg){
    QSqlQuery updateQuery(liteDB);
    QString updateSql = QString("UPDATE patient SET taskId='%1',taskOption='%2',taskStatus=%3,errMsg='%4' WHERE id=%5").arg(taskId, taskOptions, QString::number(taskStatus), errMsg, QString::number(id));
    updateQuery.prepare(updateSql);

    if(!updateQuery.exec()){
        qCritical() << updateQuery.lastError();
        return false;
    }
    return true;
}

QVector<SqlDomain::AnalysisDomain> AnalysisSql::queryDataList(){
    QSqlQuery dataQuery(liteDB);
    QString dataSql = QString("SELECT distinct patientName, testId FROM patient ORDER BY patientName");
    dataQuery.prepare(dataSql);

    if(!dataQuery.exec()){
        qCritical() << dataQuery.lastError();
        return {};
    }

    QVector<SqlDomain::AnalysisDomain> queryList;
    while(dataQuery.next()){
        queryList.push_back(SqlDomain::AnalysisDomain{
            -1, dataQuery.value(0).toString(), dataQuery.value(1).toString(), "", "", "", 0, ""
        });
    }
    return queryList;
}

QVector<SqlDomain::AnalysisDomain> AnalysisSql::queryDealList(QString patientName, QString testId){
    QSqlQuery dealQuery(liteDB);
    QString dealSql = QString("SELECT * FROM patient WHERE patientName='%1' AND testId='%2'").arg(patientName, testId);
    dealQuery.prepare(dealSql);

    if(!dealQuery.exec()){
        qCritical() << dealQuery.lastError();
        return {};
    }

    QVector<SqlDomain::AnalysisDomain> dealList;
    while(dealQuery.next()){
        dealList.push_back(SqlDomain::AnalysisDomain{
            dealQuery.value(0).toInt(), dealQuery.value(1).toString(), dealQuery.value(2).toString(),
            dealQuery.value(3).toString(), dealQuery.value(4).toString(), dealQuery.value(5).toString(),
            dealQuery.value(6).toInt(), dealQuery.value(7).toString()
        });
    }
    return dealList;
}


bool AnalysisSql::connectSqlLite(){
    if(QFile::exists("AnalysisDB.db")){
        liteDB = QSqlDatabase::addDatabase("QSQLITE");
        liteDB.setDatabaseName("AnalysisDB.db");
        if(!liteDB.open()){
            return false;
        }
    }else{
        liteDB = QSqlDatabase::addDatabase("QSQLITE");
        liteDB.setDatabaseName("AnalysisDB.db");

        if(!liteDB.open()){
            QFile::remove("AnalysisDB.db");
            return false;
        }
        if(!createDatabase()){
            QFile::remove("AnalysisDB.db");
            return false;
        }
    }
    return true;
}

bool AnalysisSql::createDatabase(){
    QSqlQuery createQuery(liteDB);

    QString sql = "CREATE TABLE \"patient\" ( \
      \"id\" integer NOT NULL PRIMARY KEY AUTOINCREMENT, \
      \"patientName\" text NOT NULL, \
      \"testId\" text NOT NULL, \
      \"imageName\" text NOT NULL, \
      \"taskId\" text, \
      \"taskOption\" text, \
      \"taskStatus\" integer, \
      \"errMsg\" text)";
    createQuery.prepare(sql);
    if(!createQuery.exec()){
        qCritical() << createQuery.lastError();
        return false;
    }

    return true;
}


AnalysisSql* AnalysisSql::pInstance = nullptr;

AnalysisSql* AnalysisSql::instance(){
    if(pInstance == nullptr){
        pInstance = new AnalysisSql();
    }
    return pInstance;
}

void AnalysisSql::release(){
    if(pInstance != nullptr){
        delete pInstance;
        pInstance = nullptr;
    }
}


AnalysisSql::AnalysisSql(QObject *parent)
    : QObject{parent} {
    if(!connectSqlLite()) throw std::runtime_error("sql connect failed");
}

QString AnalysisSql::sampleDataGenerate(){
    /*
        人名1:
            检测编号1:
                计算图像1
                计算图像2
        人名2:
            检测编号2:
                计算图像1
                计算图像2
    */
    QJsonObject caseObj;

    QJsonObject example1;
    example1.insert("123456", QJsonArray{"1.png", "2.png"});
    caseObj.insert("tacom1", example1);

    QJsonObject example2;
    example2.insert("123", QJsonArray{"1.png", "2.png"});
    caseObj.insert("tacom2", example2);

    QJsonDocument document;
    document.setObject(caseObj);
    QByteArray bArray = document.toJson(QJsonDocument::Compact);
    return QString(bArray);
}
